package com.bora_bandeco;

import static com.bora_bandeco.CommonUtilities.GCM_NOTIFICATION_REGISTRO;
import static com.bora_bandeco.CommonUtilities.GCM_NOTIFICATION_NOVO_CONVITE;
import static com.bora_bandeco.CommonUtilities.GCM_NOTIFICATION_RESPOSTA_CONVITE;
import static com.bora_bandeco.CommonUtilities.PROPERTY_FOTO_CODIFICADA;
import static com.bora_bandeco.CommonUtilities.PROPERTY_ID;
import static com.bora_bandeco.CommonUtilities.PROPERTY_NOME;
import static com.bora_bandeco.CommonUtilities.PROPERTY_NUMERO_TELEFONE;
import static com.bora_bandeco.CommonUtilities.PROPERTY_REG_ID;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.google.android.gms.gcm.GoogleCloudMessaging;

public class GcmIntentService extends IntentService {
	static final String TAG = "GCMDemo";
	
    public static final int NOTIFICATION_ID = 1;
    private NotificationManager mNotificationManager;
    NotificationCompat.Builder builder;

    public GcmIntentService() {
        super("GcmIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Bundle extras = intent.getExtras();
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
        // The getMessageType() intent parameter must be the intent you received
        // in your BroadcastReceiver.
        String messageType = gcm.getMessageType(intent);

        if (!extras.isEmpty()) {  // has effect of unparcelling Bundle
            /*
             * Filter messages based on message type. Since it is likely that GCM
             * will be extended in the future with new message types, just ignore
             * any message types you're not interested in, or that you don't
             * recognize.
             */
            if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
                sendNotification("Send error: " + extras.toString());
            } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) {
                sendNotification("Deleted messages on server: " + extras.toString());
            // If it's a regular GCM message, do some work.
            } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
            	Log.i(TAG, "Received: " + extras.toString());

            	if (extras.containsKey(GCM_NOTIFICATION_REGISTRO)) {
            		// Registro de usuário
            		String jsonContato = extras.get("contato").toString();
            		Contato contato = parseContato(jsonContato);
            		
            		Intent intentNotification = new Intent(GCM_NOTIFICATION_REGISTRO);
            		intentNotification.putExtra(PROPERTY_ID, contato.getId());
                    this.sendBroadcast(intentNotification);
            	} else if (extras.containsKey(GCM_NOTIFICATION_NOVO_CONVITE)) {
            		// Recebimento de novo convite
            		String cardapio = extras.get("cardapio").toString();
            		String jsonConvite = extras.get("convite").toString();
            		Convite convite = parseConvite(jsonConvite);
            		convite.setCardapio(cardapio);
            		convite.salvar();
            		
            		Intent intentNotification = new Intent(GCM_NOTIFICATION_NOVO_CONVITE);
            		intentNotification.putExtra(PROPERTY_ID, convite.getId());
                    this.sendBroadcast(intentNotification);
            	} else if (extras.containsKey(GCM_NOTIFICATION_RESPOSTA_CONVITE)) {
            		// Recebimento de resposta de convitex
            		int resposta = Integer.parseInt(extras.get("resposta").toString());
            		String jsonConvidado = extras.get("convidado").toString();
            		Contato convidado = parseContato(jsonConvidado);
            		
            		String jsonConvite = extras.get("convite").toString();
            		Convite convite = parseRespostaConvite(jsonConvite);
            		convite.confirmarConvidado(convidado.getId(), resposta);
            		convite.salvar();
            		
            		Intent intentNotification = new Intent(GCM_NOTIFICATION_RESPOSTA_CONVITE);
            		intentNotification.putExtra(PROPERTY_ID, convidado.getId());
                    this.sendBroadcast(intentNotification);
            	}
            	           	
                Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
                // Post notification of received message.
                //sendNotification("Received: " + extras.toString());
            }
        }
        // Release the wake lock provided by the WakefulBroadcastReceiver.
        GcmBroadcastReceiver.completeWakefulIntent(intent);
    }
    
    private Contato parseContato(String jsonString) {
    	jsonString = "[" + jsonString + "]";
    	
		try {
			JSONArray jsonArr = new JSONArray(jsonString);
		
			if (jsonArr != null) {
				int lenght = jsonArr.length();
                 
				for (int i = 0; i < lenght; i++) {
					JSONObject jsonObj = jsonArr.getJSONObject(i);
            	 	
					int id = jsonObj.getInt("_id");
                 	String nome = jsonObj.getString("nome");
                 	String numeroTelefone = jsonObj.getString("numero_telefone");
                 	
                 	Contato contato = new Contato();
                 	contato.setId(id);
                 	contato.setNome(nome);
                 	contato.setNumeroTelefone(numeroTelefone);
                 	
                 	return contato;
                 }
			 }
		} catch (JSONException e) {
			// 
		}
		return null;
    }
    
    private Convite parseConvite(String jsonString) {
    	jsonString = "[" + jsonString + "]";
    	
		try {
			JSONArray jsonArr = new JSONArray(jsonString);
		
			if (jsonArr != null) {
				int lenght = jsonArr.length();
                 
				for (int i = 0; i < lenght; i++) {
					JSONObject jsonObj = jsonArr.getJSONObject(i);
            	 	
					int id = jsonObj.getInt("_id");
                 	String restaurante = jsonObj.getString("restaurante");
                 	long horario = jsonObj.getLong("horario");
                 	
                 	Convite convite = new Convite();
		        	convite.setId(id);
		        	convite.setRestaurante(restaurante);
		        	convite.setHorario(horario);

		        	// Pode ser que o anfitrião não exista na base de dados
		        	// assim, por precaução faz-se SET dos dados recebidos
					JSONObject anfitriaoObj = jsonObj.getJSONObject("anfitriao");
		        	int idAnfitriao = anfitriaoObj.getInt("_id");
		        	String nomeAnfitriao = anfitriaoObj.getString("nome");
		        	String numeroTelefoneAnfitriao = anfitriaoObj.getString("numero_telefone");
		        	
		        	Contato anfitriao = new Contato(idAnfitriao);
		        	anfitriao.setNome(nomeAnfitriao);
		        	anfitriao.setNumeroTelefone(numeroTelefoneAnfitriao);
		        	convite.setAnfitriao(anfitriao);
                 	
        			JSONArray convidados = jsonObj.getJSONArray("convidados");
	            	
	            	if (convidados != null) {
	    				int nConvidados = convidados.length();
	    				
	    				for (int j = 0; j < nConvidados; j++) {
	    					JSONObject convidadoObj = convidados.getJSONObject(j);
	    					int idConvidado = convidadoObj.getInt("_id");
	                    	String nomeConvidado = convidadoObj.getString("nome");
	                    	String numeroTelefoneConvidado = convidadoObj.getString("numero_telefone");
	                    	int resposta = convidadoObj.getInt("resposta");
	                    	
	                    	Convidado convidado = new Convidado(idConvidado);
	                    	convidado.setNome(nomeConvidado);
	                    	convidado.setNumeroTelefone(numeroTelefoneConvidado);
	                    	convidado.setResposta(resposta);
	    		        	
	                    	convite.addConvidados(convidado);
	    				}
	            	}
		        	
                 	return convite;
                 }
			 }
		} catch (JSONException e) {
			// 
		}
		return null;
    }
    
    private Convite parseRespostaConvite(String jsonString) {
    	jsonString = "[" + jsonString + "]";
    	
		try {
			JSONArray jsonArr = new JSONArray(jsonString);
		
			if (jsonArr != null) {
				int lenght = jsonArr.length();
                 
				for (int i = 0; i < lenght; i++) {
					JSONObject jsonObj = jsonArr.getJSONObject(i);
            	 	
					int id = jsonObj.getInt("_id");
                 	String restaurante = jsonObj.getString("restaurante");
                 	long horario = jsonObj.getLong("horario");
                 	
                 	Convite convite = new Convite(id);
		        	convite.setRestaurante(restaurante);
		        	convite.setHorario(horario);

		        	int idAnfitriao = jsonObj.getInt("anfitriao");
		        	
		        	Contato anfitriao = new Contato(idAnfitriao);
		        	convite.setAnfitriao(anfitriao);
                 	
        			JSONArray convidados = jsonObj.getJSONArray("convidados");
	            	
	            	if (convidados != null) {
	    				int nConvidados = convidados.length();
	    				
	    				for (int j = 0; j < nConvidados; j++) {
	    					JSONObject convidadoObj = convidados.getJSONObject(j);
	    					int idConvidado = convidadoObj.getInt("_id");
	                    	int resposta = convidadoObj.getInt("resposta");
	                    	
	                    	Convidado convidado = new Convidado(idConvidado);
	                    	convidado.setResposta(resposta);
	    		        	
	                    	convite.addConvidados(convidado);
	    				}
	            	}
		        	
                 	return convite;
                 }
			 }
		} catch (JSONException e) {
			// 
		}
		return null;
    }
    
    // Put the message into a notification and post it.
    // This is just one simple example of what you might choose to do with
    // a GCM message.
    private void sendNotification(String msg) {
        mNotificationManager = (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);

        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, CardapioActivity.class), 0);

        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(this)
        .setSmallIcon(R.drawable.ic_launcher)
        .setContentTitle("GCM Notification")
        .setStyle(new NotificationCompat.BigTextStyle()
        .bigText(msg))
        .setContentText(msg);

        mBuilder.setContentIntent(contentIntent);
        mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
    }
}